package club.xyes.remotedisplay.screen;

import club.xyes.remotedisplay.jni.AbstractOLEDScreen;
import club.xyes.remotedisplay.jni.SSD1306;
import club.xyes.remotedisplay.util.ArrayUtil;
import club.xyes.remotedisplay.util.ByteUtil;
import club.xyes.remotedisplay.util.StringBitmapUtil;

/**
 * 2018/11/12 Create by 郭文梁
 * Screen12864
 * SSD1306 IIC 12864驱动
 *
 * @author 郭文梁
 * @date 2018/11/12
 */
public class Screen12864 extends AbstractOLEDScreen {
    private static final int WIDTH = 128;
    private static final int HEIGHT = 64;
    private static final int ONE_BYTE = 8;
    private static final int PAGE_SIZE = HEIGHT / ONE_BYTE;
    /**
     * 位图内存缓存映射
     */
    private final int[][] bitmap = new int[PAGE_SIZE][];

    public Screen12864() {
        initBitmap();
    }

    /**
     * 初始化位图映射缓存
     */
    private void initBitmap() {
        for (int i = 0; i < PAGE_SIZE; i++) {
            bitmap[i] = new int[WIDTH];
        }
    }

    @Override
    public void display() {
        setPosition(0, 0);
        fill(bitmap);
    }

    @Override
    public void fill(int[][] data) {
        int[] dataArr = ArrayUtil.flat(data);
        fill(dataArr);
    }

    @Override
    public void on() {
        fill(bitmap);
    }

    @Override
    public void off() {
        int[] data = new int[WIDTH * HEIGHT / ONE_BYTE];
        setPosition(0, 0);
        fill(data);
    }

    @Override
    public void setPosition(int x, int y) {
        SSD1306.ssd1306Command(SSD1306.SSD1306_COLUMNADDR);
        SSD1306.ssd1306Command(x);
        SSD1306.ssd1306Command(WIDTH - 1);
        SSD1306.ssd1306Command(SSD1306.SSD1306_PAGEADDR);
        SSD1306.ssd1306Command(y);
        SSD1306.ssd1306Command(PAGE_SIZE - 1);
    }

    @Override
    public void drawString(String str, String font, int size, int x, int y) {
        int margin = size / 6;
        short[][] data = StringBitmapUtil.toBitmap(str,
                font,
                size - margin,
                size,
                false,
                margin,
                StringBitmapUtil.VERTICAL,
                StringBitmapUtil.HORIZONTAL
        );
        int[][] bitmap = ArrayUtil.toIntArray(data);
        ByteUtil.reverse(bitmap);

        for (int i = 0; i < bitmap.length; i++) {
            int[] line = bitmap[i];
            setPosition(x, y + i);
            fill(line);
        }
    }

    @Override
    public void clear() {
        for (int y = 0; y < PAGE_SIZE; y++) {
            for (int x = 0; x < WIDTH; x++) {
                bitmap[y][x] = 0;
            }
        }
        display();
    }

    @Override
    public void show() {
        setPosition(0, 0);
        fill(bitmap);
    }

    @Override
    public void superposition(int x, int y, int[] data) {
        int upPage = y / ONE_BYTE;
        int[] upLine = bitmap[upPage];

        ByteUtil.superposition(upLine, data, x, y % ONE_BYTE);

        if (y % ONE_BYTE == 0) {
            //正好在整数页
            return;
        }

        int[] downLine = bitmap[upPage + 1];
        ByteUtil.superposition(downLine, data, x, ONE_BYTE - (y % ONE_BYTE));
    }

}
